/***************************************************************************************************
*Copyright(C),2010-2016,Sumscope
*FileName	:  gbkmap.cpp
*Author	:  scofined.qi
*Version	:  1.0
*Date		:  2015/12/22
*Desc		:  //用于主要说明此程序文件完成的主要功能
*Relation :  
*Others	:  //其他内容说明
*Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
*History	:  //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
***************************************************************************************************/
#include "gbkmap.h"
namespace qb{
	namespace base{


		////////////////////////////////////////////////////////////////////////////////
	CGbkMap::GbkArea::GbkArea(ushort p1,ushort p2,kGbkHanziType t,int num):
		type(t),count(num),
		hiBottom(p1&0x00ff),hiTop(p2&0x00ff),
		lowLeft((p1&0xff00)>>8),lowRight((p2&0xff00)>>8)
	{
		has7f = hiTop>0x7F && hiBottom<0x7F;
	}

	bool CGbkMap::GbkArea::exist(uchar x,uchar y)
	{
		return x>=lowLeft  && x<=lowRight &&
			y>=hiBottom && y<=hiTop;
	}
	unsigned short CGbkMap::GbkArea::get(int i)
	{
		ushort x,y,h;
		h = hiTop-hiBottom+(has7f?0:1);
		y = hiBottom +i%h;
		if(has7f && y>=0x7f){y++;}
		x = lowLeft+i/h;
		ushort gbk = ((y&0x00ff)<<8)|x;
		return gbk;
	}


	CGbkMap::CGbkMap(){
		m_areas[kGbkHanziTypeGbk1]	=GbkArea(0xA1A1,0xA9FE,kGbkHanziTypeGbk1,717);
		m_areas[kGbkHanziTypeGbk2]	=GbkArea(0xB0A1,0xF7FE,kGbkHanziTypeGbk2,6763);	// D7,FA-FE 没有对应汉字
		m_areas[kGbkHanziTypeGbk3]	=GbkArea(0x8140,0xA0FE,kGbkHanziTypeGbk3,6080);
		m_areas[kGbkHanziTypeGbk4]	=GbkArea(0xAA40,0xFEA0,kGbkHanziTypeGbk4,8160);
		m_areas[kGbkHanziTypeGbk5]	=GbkArea(0xA840,0xA9A0,kGbkHanziTypeGbk5,166);
		m_areas[kGbkHanziTypeUser1]	=GbkArea(0xAAA1,0xAFFE,kGbkHanziTypeUser1,564);
		m_areas[kGbkHanziTypeUser2]	=GbkArea(0xF8A1,0xFEFE,kGbkHanziTypeUser2,658);
		m_areas[kGbkHanziTypeUser3]	=GbkArea(0xA140,0xA7A0,kGbkHanziTypeUser3,672);
	}
	bool CGbkMap::IsGbkCode(const unsigned char* gbk)
	{
		kGbkHanziType type =  GetGbkType(gbk);
		return type == kGbkHanziTypeGbk2 ||
			type == kGbkHanziTypeGbk3 ||
			type == kGbkHanziTypeGbk4 ||
			type == kGbkHanziTypeGbk1 ||
			type == kGbkHanziTypeGbk5;
	}
	bool CGbkMap::IsHanzi(const unsigned char* gbk)
	{
		kGbkHanziType type =  GetGbkType(gbk);
		return type == kGbkHanziTypeGbk2 ||
			type == kGbkHanziTypeGbk3 ||
			type == kGbkHanziTypeGbk4;
	}
	kGbkHanziType CGbkMap::GetGbkType(const unsigned char* gbk)
	{
		uchar x = *gbk;
		uchar y = *(gbk+1);
		if(y==0x7F || y==0xFF)
			return kGbkHanziTypeCount;
		for (int i=0;i<kGbkHanziTypeCount;i++)
		{
			if(m_areas[i].exist(x,y))
				return kGbkHanziType(i);
		}
		return kGbkHanziTypeCount;
	}
	int CGbkMap::GetCount()
	{
		int sum = 0;
		for (int i=0;i<kGbkHanziTypeCount;i++){sum += m_areas[i].count;}
		return sum;
	}
	BaseString CGbkMap::GetAreaString(kGbkHanziType type)
	{
		int count = GetHanziCount(type)*2+2;
		char* buf = new char[count];
		memset(buf,0,count);
		GetAreaString(type,buf,count);
		BaseString str = buf;
		delete [] buf;
		return str;
	}
	int CGbkMap::GetAreaString(kGbkHanziType type,char* buf,int count)
	{
		int num = m_areas[type].count*2;
		if(buf==NULL || count<num+2)
			return num+2;

		count = m_areas[type].count;
		for (int i=0;i<count;i++)
		{
			unsigned short s = GetHanzi(type,i);
			*((unsigned short*)&buf[i*2]) = s;
		}
		return count*2;
	}
	bool CGbkMap::IsGbkString(const char* buf,int len)
	{
		int alpha = 0;
		const unsigned char* str = (const unsigned char*)buf;
		int hanzi[kGbkHanziTypeCount+1]={0};
		for (int i=0;i<len;i++)
		{
			if(str[i]<127)
				alpha++;
			else
			{
				kGbkHanziType type = GetGbkType((const unsigned char*)(str+i));
				hanzi[type]= hanzi[type]+1;
				i++;
			}
		}
		return hanzi[kGbkHanziTypeUser1]<=0 &&
			hanzi[kGbkHanziTypeUser2]<=0 &&
			hanzi[kGbkHanziTypeUser3]<=0 &&
			hanzi[kGbkHanziTypeCount]<=0;
	}
	bool CGbkMap::IsVisibleChar(unsigned char c)
	{
		// 只允许可见的ascii字符：从0x20(space)到0x7e(~)以及\t
		// (sp)  ~
		return (c>=0x20 && c<=0x7e) || c=='\t';
	}
	}//namespace base;
}//namespace ss;
